/***********************************************************************************
 * 文件名： polsys.c
 * 版本： 2
 * 说明：
 * 		polsys 核心实现。 
 *      【polsys】
 *      使用软定时器原理的“多任务”系统, 轮询调用入口函数，非RTOS。支持在任意地方创建任务。
 *      【polsys_lite】
 *      通过在用户端提供宏定义配置的方式让用户添加几个固定间隔时间需要执行的任务函数，然后在
 *  Polsys_Loop 定时调用他们。 这样的机制可以在不支持函数指针的“低端RISC 8位单片机”中帮助代
 *  码去耦，让软件更具模块化和面向对象。
 *      main.c 文件中已经编写好程序入口函数，用户只需要将main.c添加到工程即可。然后还需要
 *  在一个定时器中断中调用 Polsys_Tick() ，详见头文件。
 * 修改记录：
 * 	2021/04/28: 初版。 刘言。
 *  2021/05/19：合并polsys。刘言。
***********************************************************************************/
#include "polsys.h"

#ifdef POLSYS_LITE

bit _Polsys_mTicked = false;

// #ifdef _POLSYS_TASK_GROUP_1000TICK
// u8 _Polsys_TickCount = 0;
// u8 _Polsys_10TickCount = 0;
// u8 _Polsys_100TickCount = 0;
// #elif (defined _POLSYS_TASK_GROUP_100TICK)
// u8 _Polsys_TickCount = 0;
// u8 _Polsys_10TickCount = 0;
// #elif (defined _POLSYS_TASK_GROUP_10TICK)
// u8 _Polsys_TickCount = 0;
// #endif
u8 _Polsys_TickCount = 0;
#else
//自定义数据类型

typedef struct _sys_info
{
	polsys_task_t *Tasks[POLSYS_MAX_TASKS]; //所有的任务列表
	u8 NowRunTaskNo;			   //现在正在运行的任务号
	u8 TotalTask;				   //已添加的任务数量
} sys_info;

static idata sys_info mSysInfo;

void Polsys_Tick() //定时器中断调用 系统节拍 间隔 POLSYS_TICK_CYCLE ms
{
	u8 i;
	polsys_task_t *cTask;

	for (i = 0; i < mSysInfo.TotalTask; i++)
	{
		cTask = mSysInfo.Tasks[i];

		if (cTask->WaitTime > 0)
			cTask->WaitTime--;
		if (cTask->WaitTime == 0)
		{
			cTask->Status = TS_READY;
			cTask->WaitTime = cTask->Interval;
		}
	}
}

void Polsys_Loop() //系统循环，用于执行任务，始终循环调用
{
	u8 i;
	polsys_task_t *cTask;
	bool EnterIdle = true;

	for (i = 0; i < mSysInfo.TotalTask; i++)
	{
		cTask = mSysInfo.Tasks[i];

		if (cTask->Status == TS_READY)
		{
			if (cTask->Interval > 0)
				cTask->Status = TS_WAIT; //标记为等待状态，没有间隔时间的任务不标记，始终READY
			else
				EnterIdle = false;
			mSysInfo.NowRunTaskNo = i;
			cTask->EntryFunc();
		}
	}
	//READY的任务执行完毕了，如果没有Interval=0的任务，进入空闲任务
	if (EnterIdle)
		SYS_IDLE();
}

void Polsys_Init()
{
	_Polsys_ClockInit();	//系统时钟初始化
	mSysInfo.NowRunTaskNo = 0;
	mSysInfo.TotalTask = 0;
	_Polsys_TickStart();
	Polsys_EnableInt();
}

bool Polsys_TaskInit(polsys_task_t *task_ptr, void (*Entry)(void), u16 Interval)
{
	if (mSysInfo.TotalTask >= POLSYS_MAX_TASKS)
		return false;

	// task 属性
	task_ptr->EntryFunc = Entry;
	task_ptr->Interval = Interval;
	task_ptr->WaitTime = Interval;
	task_ptr->Status = TS_WAIT;

	//添加到 task 列表
	mSysInfo.Tasks[mSysInfo.TotalTask] = task_ptr;

	mSysInfo.TotalTask++;

	return true;
}

#endif
